package clubhouse.error;

import clubhouse.base.Base;

/**
 * @author Anis Darwich & Lionel Croix - Simulation and experimentation on Robot in WSN - WnSN Lab - SJTU
 */
public class TransmissionError {
 
	/**Current error attenuation factor.*/
	private int errorFactor;
	
	/**
	 * Constructs the TransmissionError object.
	 */
	public TransmissionError() {
	}
	
	/**
	 * Set error factor to the specified value in the corresponding field in GUI.
	 * @param error the new error attenuation factor to set.
	 */
	public void setErrorFactor(int error) {
		this.errorFactor = error;
	}
	
	/**
	 * Return the new coordinates of the landmark after applying an uniform distributed error.
	 * <br/>The error value is weighted by the euclidean distance between the robot and the current node divided 
	 * by the error attenuation factor.
	 * @param x_robot X coordinate of current robot position.
	 * @param y_robot Y coordinate of current robot position.
	 * @param x_node X coordinate of current node.
	 * @param y_node Y coordinate of current node.
	 * @return the double array containing node coordinates after applying error.
	 */
	public double[] applyError(double x_robot, double y_robot, double x_node, double y_node) {
		double[] result = new double [2];
		double distance;
				
		distance = Base.euclideanDist(x_robot,y_robot,x_node,y_node);
		do {
			result[0] = x_node + (Math.random()*2-1)*distance/this.errorFactor;	//Random uniform Distribution
			result[1] = y_node + (Math.random()*2-1)*distance/this.errorFactor;
			} while (Base.euclideanDist(x_node,y_node,result[0],result[1]) > distance/this.errorFactor);
		return result;
	}
	
	/**
	 * Return the new coordinates of the landmark after applying error using the given error element extract form pool.
	 * <br/>The error value is weighted by the euclidean distance between the robot and the current node divided 
	 * by the error attenuation factor.
	 * @param err the error from pool to apply, this value is weighted by the euclidean distance between the robot and the current node divided 
	 * by the error attenuation factor.
	 * @param x_robot X coordinate of current robot position.
	 * @param y_robot Y coordinate of current robot position.
	 * @param x_node X coordinate of current node.
	 * @param y_node Y coordinate of current node.
	 * @return the double array containing node coordinates after applying error.
	 */
	public double[] applyErrorFromPool(double err, double x_robot, double y_robot, double x_node, double y_node) {
		double[] result = new double [2];
		double distance;
				
		distance = Base.euclideanDist(x_robot,y_robot,x_node,y_node);
		result[0] = x_node + err*distance/this.errorFactor;
		result[1] = y_node + err*distance/this.errorFactor;
		
		return result;
	}
}
